//
// CrackUpdaterEntry
//
// Copyright (C) jextra.net.
//
//  This file is part of the Crack build system.
//
//  The Crack build system is free software; you can redistribute it 
//  and/or modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  The Crack build system is distributed in the hope that it will be 
//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with the Crack build system; if not, write to the Free
//  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
//  02111-1307 USA.
//

package net.jextra.crack.updater;

import java.io.*;
import java.security.*;
import org.apache.commons.codec.binary.*;

public class CrackUpdaterEntry implements Comparable<CrackUpdaterEntry>
{
    // ============================================================
    // Enums
    // ============================================================

    public enum Type
    {
        file( "f" ),
        directory( "d" );

        private String tag;

        Type( String tag )
        {
            this.tag = tag;
        }

        public static Type getTagType( String tag )
        {
            for ( Type type : values() )
            {
                if ( type.tag().equals( tag ) )
                {
                    return type;
                }
            }

            return null;
        }

        public String tag()
        {
            return tag;
        }

        @Override
        public String toString()
        {
            return tag();
        }
    }

    // ============================================================
    // Fields
    // ============================================================

    public static final int BUFFER_SIZE = 50000;

    private String _path;
    private Type _type;
    private long _timestamp;
    private long _size;
    private String _sha256Hash;

    // ============================================================
    // Constructors
    // ============================================================

    public CrackUpdaterEntry( String path, Type type, long timestamp, long size, String sha256Hash )
    {
        assert path != null;
        assert type != null;

        _path = path;
        _type = type;
        _timestamp = timestamp;
        _size = size;
        _sha256Hash = sha256Hash;
    }

    // ============================================================
    // Methods
    // ============================================================

    // ----------
    // public
    // ----------

    public static String getSHA256Hash( File file )
        throws NoSuchAlgorithmException, IOException
    {
        if ( file.isDirectory() )
        {
            return null;
        }

        FileInputStream in = new FileInputStream( file );
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        byte[] buf = new byte[BUFFER_SIZE];
        int i = 0;
        while ( ( i = in.read( buf ) ) != -1 )
        {
            out.write( buf, 0, i );
        }
        in.close();
        out.close();

        MessageDigest digest = MessageDigest.getInstance( "SHA-256" );
        digest.reset();
        byte[] hash = digest.digest( out.toByteArray() );

        Hex hex = new Hex();
        String hashString = new String( hex.encode( hash ) );
        return hashString;
    }

    public boolean isFile()
    {
        return getType() == Type.file;
    }

    public boolean isDirectory()
    {
        return getType() == Type.directory;
    }

    public Type getType()
    {
        return _type;
    }

    public void setType( Type type )
    {
        _type = type;
    }

    public String getPath()
    {
        return _path;
    }

    public void setPath( String path )
    {
        _path = path;
    }

    public long getTimestamp()
    {
        return _timestamp;
    }

    public void setTimestamp( long timestamp )
    {
        _timestamp = timestamp;
    }

    public long getSize()
    {
        return _size;
    }

    public void setSize( long size )
    {
        _size = size;
    }

    public String getSHA256Hash()
    {
        return _sha256Hash;
    }

    public void setSHA256Hash( String sha256Hash )
    {
        _sha256Hash = sha256Hash;
    }

    @Override
    public boolean equals( Object obj )
    {
        if ( !( obj instanceof CrackUpdaterEntry ) )
        {
            return false;
        }

        CrackUpdaterEntry other = (CrackUpdaterEntry) obj;

        if ( !_path.equals( other._path ) )
        {
            return false;
        }

        return true;
    }

    @Override
    public int compareTo( CrackUpdaterEntry other )
    {
        if ( isDirectory() && !other.isDirectory() )
        {
            return -1;
        }
        else if ( !isDirectory() && other.isDirectory() )
        {
            return 1;
        }

        return _path.compareTo( other._path );
    }
}
